/*
 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include "iot_errno.h"
#include "iot_pwm.h"
#include "iot_i2c.h"
#include "iot_adc.h"
#include "hi_time.h"
#include "hi_io.h"
#include "hi_errno.h"
#include "hi_adc.h"
#include "pca9555.h"
#include "ssd1306_fonts.h"
#include "oled_ssd1306.h"

#include <stdio.h>
#include <string.h>
#include "iot_config.h"
#include "iot_main.h"
#include "iot_profile.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_connecter.h"
#include "iot_gpio_ex.h"
#include "iot_gpio.h"
#include "iot_watchdog.h"
#include "cjson_init.h"
#include "hi_stdlib.h"
#include "app_demo_iot.h"

/* attribute initiative to report */
#define TAKE_THE_INITIATIVE_TO_REPORT
/* oc request id */
#define CN_COMMAND_INDEX                    "commands/request_id="
/* oc report HiSpark attribute */
#define TRAFFIC_LIGHT_CMD_CONTROL_MODE      "ControlModule"
#define TRAFFIC_LIGHT_RED_ON_PAYLOAD        "RED_LED_ON"
#define TRAFFIC_LIGHT_RED_OFF_PAYLOAD        "RED_LED_OFF"

#define TASK_SLEEP_1000MS (1000)
int g_lightStatus = -1;

// 线程创建参数
#define NUM 1
#define STACK_SIZE 1024
// MQ-7参数配置
#define MQ7_ADC_CHANNEL IOT_ADC_CHANNEL_2  // 使用ADC通道2
#define MQ7_AO_PIN IOT_IO_NAME_GPIO_6     // AO引脚连接GPIO6(ADC输入)
#define MQ7_DO_PIN IOT_IO_NAME_GPIO_5    // DO引脚连接GPIO5(数字输入)
#define DANGER_THRESHOLD 1100              // 危险阈值
static uint32_t gas_value = 0;            // 全局变量，存储气体浓度值
// 光敏传感器参数配置
#define LIGHT_ADC_CHANNEL IOT_ADC_CHANNEL_3  // 使用ADC通道3
#define LIGHT_AO_PIN IOT_IO_NAME_GPIO_7     // AO引脚连接GPIO7
#define LIGHT_DO_PIN IOT_IO_NAME_GPIO_8    // DO引脚连接GPIO8 
#define LIGHT_THRESHOLD 600                // 光线阈值
static uint32_t light_value = 0;           // 全局变量，存储光线强度值
// 交通灯参数配置
#define DWHITE_LED 0x38+0x07

// MQ-7初始化函数
void MQ7_Init(void)
{
    // 初始化AO引脚(ADC通道)
    IoTGpioInit(MQ7_AO_PIN);
    IoSetFunc(MQ7_AO_PIN, IOT_IO_FUNC_GPIO_6_GPIO);
    IoTGpioSetDir(MQ7_AO_PIN, IOT_GPIO_DIR_IN);
    
    // 初始化DO引脚(数字输入)
    IoTGpioInit(MQ7_DO_PIN);
    IoSetFunc(MQ7_DO_PIN, IOT_IO_FUNC_GPIO_5_GPIO);
    IoTGpioSetDir(MQ7_DO_PIN, IOT_GPIO_DIR_IN);
    
    printf("MQ-7 sensor initialized\r\n");
}
// 获取MQ-7传感器值
void GetMQ7Data(void)
{
    unsigned short data = 1;
    IotGpioValue do_value;
    
    // 读取AO模拟值
    int ret = AdcRead(MQ7_ADC_CHANNEL, &data, IOT_ADC_EQU_MODEL_4, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != IOT_SUCCESS) {
        printf("MQ-7 AO read failed\n");
        return;
    }

    // 读取DO数字值
    IoTGpioGetInputVal(MQ7_DO_PIN, &do_value);
    
    gas_value = data; // 更新全局变量
    printf("MQ-7 AO: %d, DO: %d\r\n", data, do_value);
}
// MQ-7检测线程
void MQ7DetectionTask(void)
{
    printf("MQ7DetectionTask init\r\n");
    MQ7_Init();  // 初始化MQ-7传感器
    
    while (1) {
        GetMQ7Data();  // 获取MQ-7数据
        osDelay(500); // 3秒采样间隔
    }
}

// 光敏传感器初始化
void LightSensor_Init(void)
{
    // 初始化AO引脚(ADC通道)
    IoTGpioInit(LIGHT_AO_PIN);
    IoSetFunc(LIGHT_AO_PIN, IOT_IO_FUNC_GPIO_7_GPIO);
    IoTGpioSetDir(LIGHT_AO_PIN, IOT_GPIO_DIR_IN);
    
    // 初始化DO引脚(数字输入)
    IoTGpioInit(LIGHT_DO_PIN);
    IoSetFunc(LIGHT_DO_PIN, IOT_IO_FUNC_GPIO_8_GPIO);
    IoTGpioSetDir(LIGHT_DO_PIN, IOT_GPIO_DIR_IN);
    
    printf("Light sensor initialized\r\n");
}
// 获取光敏传感器值
void GetLightData(void)
{
    unsigned short data = 0;
    IotGpioValue do_value;
    
    // 读取AO模拟值
    int ret = AdcRead(LIGHT_ADC_CHANNEL, &data, IOT_ADC_EQU_MODEL_4, 
                     IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != IOT_SUCCESS) {
        printf("Light sensor AO read failed\n");
        return;
    }
    
    // 读取DO数字值
    IoTGpioGetInputVal(LIGHT_DO_PIN, &do_value);
    
    light_value = data; // 更新全局变量
    printf("Light AO: %d, DO: %d\r\n", data, do_value);
}
// 光敏检测线程
void LightDetectionTask(void)
{
    printf("LightDetectionTask init\r\n");
    
    while (1) {
        GetLightData();
        osDelay(500); // 3秒采样间隔
    }
}

void IotPublishSample(void)
{

    IoTProfileService service;
    IoTProfileKV properties1;
    IoTProfileKV properties2;

    char line1[32] = {0};
    int dis_value = gas_value - 690;
    snprintf(line1, sizeof(line1), "%d", dis_value);
    char line2[32] = {0};
    int display_value = light_value + 800;
    snprintf(line2, sizeof(line2), "%d", display_value);

    printf("Reporting sensor data\r\n");
    
    // 气体浓度属性
    memset_s(&properties1, sizeof(IoTProfileKV), 0, sizeof(IoTProfileKV));
    properties1.type = EN_IOT_DATATYPE_STRING;
    properties1.key = "GasConcentration";
    properties1.value = line1;
    
    memset_s(&service, sizeof(service), 0, sizeof(service));
    service.serviceID = "EnvironmentSensor";  // 修改服务ID
    service.serviceProperty = &properties1;

    IoTProfilePropertyReport(CONFIG_DEVICE_ID, &service);  
    
    // 光照强度属性
    memset_s(&properties2, sizeof(IoTProfileKV), 0, sizeof(IoTProfileKV));
    properties2.type = EN_IOT_DATATYPE_STRING;
    properties2.key = "LightIntensity";
    properties2.value = line2;

    memset_s(&service, sizeof(service), 0, sizeof(service));
    service.serviceID = "EnvironmentSensor";  // 修改服务ID
    service.serviceProperty = &properties2; 
    
    IoTProfilePropertyReport(CONFIG_DEVICE_ID, &service);  
}

// /< this is the demo main task entry,here we will set the wifi/cjson/mqtt ready ,and
// /< wait if any work to do in the while
static void DemoEntry(void)
{
    ConnectToHotspot();
    //RedLedInit();
    CJsonInit();
    IoTMain();
    //IoTSetMsgCallback(DemoMsgRcvCallBack);
    TaskMsleep(30000); // 30000 = 3s连接华为云
/* 主动上报 */
    while (1) {
        // here you could add your own works here--we report the data to the IoTplatform
        TaskMsleep(5*TASK_SLEEP_1000MS);
        // know we report the data to the iot platform
        IotPublishSample();
    }
}

// This is the demo entry, we create a task here, and all the works has been done in the demo_entry
#define CN_IOT_TASK_STACKSIZE  0x1000
#define CN_IOT_TASK_PRIOR 28
#define CN_IOT_TASK_NAME "IOTDEMO"
static void AppDemoIot(void)
{
    MQ7_Init();
    LightSensor_Init();

    osThreadAttr_t attr;
    IoTWatchDogDisable();
    attr.name = "IOTDEMO";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = CN_IOT_TASK_STACKSIZE;
    attr.priority = CN_IOT_TASK_PRIOR;

    if (osThreadNew((osThreadFunc_t)DemoEntry, NULL, &attr) == NULL) {
        printf("[TrafficLight] Failed to create IOTDEMO!\n");
    }

    attr.name = "Thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = STACK_SIZE;
    attr.priority = osPriorityNormal;

    // 创建MQ-7检测线程
    osThreadNew((osThreadFunc_t)MQ7DetectionTask, NULL, &attr); 
    // 创建光敏检测线程
    osThreadNew((osThreadFunc_t)LightDetectionTask, NULL, &attr); 
}

SYS_RUN(AppDemoIot);